package io.gitee.vexlife.snake.ui;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.*;

import io.gitee.vexlife.snake.GameController;
import io.gitee.vexlife.snake.IAgent;
import io.gitee.vexlife.snake.basic.Direction;
import io.gitee.vexlife.snake.basic.Food;
import io.gitee.vexlife.snake.basic.Node;
import io.gitee.vexlife.snake.basic.Snake;

public class MainFrame extends JFrame {
	private static final long serialVersionUID = 1L;
	private GameController gmctrl;
	private JMenu agentMenu;

	public MainFrame(GameController gmctrl) {
		super("贪吃蛇游戏");
		this.gmctrl = gmctrl;

		this.setDefaultCloseOperation(EXIT_ON_CLOSE);

		JMenu game = new JMenu("游戏");
		JMenuItem begin = new JMenuItem("新局");
		begin.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				gmctrl.startGame();
			}
		});
		game.add(begin);
		JMenuItem pause = new JMenuItem("暂停");
		pause.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				gmctrl.setOver(true);
			}
		});
		game.add(pause);
		JMenuItem resume = new JMenuItem("继续");
		resume.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				if (gmctrl.isOver())
					gmctrl.continueGame();
			}
		});
		game.add(resume);
		JMenuItem settings = new JMenuItem("设置");
		settings.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				gmctrl.settingsCollector.setVisible(true);
				;
			}
		});
		game.add(settings);

		agentMenu = new JMenu("引擎");

		JMenuBar menu = new JMenuBar();
		menu.add(game);
		menu.add(agentMenu);
		this.setJMenuBar(menu);

		JPanel board = new JPanel() {

			@Override
			public void paint(Graphics g) {
				this.paint(g, gmctrl.getSnake(), gmctrl.getFood());
			}

			public void paint(Graphics g, Snake snake, Food food) {
				Image iBuffer = this.createImage(this.getWidth(), this.getHeight());
				Graphics gBuffer = iBuffer.getGraphics();
				gBuffer.setColor(gmctrl.color_Background);
				gBuffer.fillRect(0, 0, this.getWidth(), this.getHeight());
				for (int i = 0; i < snake.getNodes().size() - 1; i++) {
					Node prev = snake.getNodes().get(i);
					Node next = snake.getNodes().get(i + 1);
					gBuffer.setColor(gmctrl.color_Snake);
					gBuffer.fillRect(
							Math.min(prev.getX(), next.getX()) * gmctrl.UNIT_SIZE
									+ (gmctrl.UNIT_SIZE - gmctrl.SNAKE_STROKE) / 2,
							Math.min(prev.getY(), next.getY()) * gmctrl.UNIT_SIZE
									+ (gmctrl.UNIT_SIZE - gmctrl.SNAKE_STROKE) / 2,
							Math.abs(next.getX() - prev.getX()) * gmctrl.UNIT_SIZE + gmctrl.SNAKE_STROKE,
							Math.abs(next.getY() - prev.getY()) * gmctrl.UNIT_SIZE + gmctrl.SNAKE_STROKE);
				}
				gBuffer.setColor(gmctrl.color_Food);
				switch (gmctrl.shape_Food) {
				case SQUARE:
					gBuffer.fillRect(
							food.getFoodNode().getX() * gmctrl.UNIT_SIZE + (gmctrl.UNIT_SIZE - gmctrl.FOOD_STROKE) / 2,
							food.getFoodNode().getY() * gmctrl.UNIT_SIZE + (gmctrl.UNIT_SIZE - gmctrl.FOOD_STROKE) / 2,
							gmctrl.FOOD_STROKE, gmctrl.FOOD_STROKE);
					break;
				case CIRCLE:
					gBuffer.fillRoundRect(
							food.getFoodNode().getX() * gmctrl.UNIT_SIZE + (gmctrl.UNIT_SIZE - gmctrl.FOOD_STROKE) / 2,
							food.getFoodNode().getY() * gmctrl.UNIT_SIZE + (gmctrl.UNIT_SIZE - gmctrl.FOOD_STROKE) / 2,
							gmctrl.FOOD_STROKE, gmctrl.FOOD_STROKE, gmctrl.FOOD_STROKE, gmctrl.FOOD_STROKE);
					break;
				}
				g.drawImage(iBuffer, 0, 0, this);
			}

		};
		board.setPreferredSize(new Dimension(this.gmctrl.UNIT_SIZE * this.gmctrl.getWidth(),
				this.gmctrl.UNIT_SIZE * this.gmctrl.getHeight()));
		this.add(board);

		this.pack();
		this.setResizable(false);

		this.addKeyListener(new KeyListener() {

			@Override
			public void keyTyped(KeyEvent e) {

			}

			@Override
			public void keyPressed(KeyEvent e) {

			}

			@Override
			public void keyReleased(KeyEvent e) {
				if (gmctrl.isActivated() && gmctrl.getSelectedAgent() == null) {
					switch (e.getKeyCode()) {
					case KeyEvent.VK_LEFT:
						gmctrl.getSnake().turn(Direction.LEFT);
						break;
					case KeyEvent.VK_RIGHT:
						gmctrl.getSnake().turn(Direction.RIGHT);
						break;
					}
					gmctrl.setActivatedFlag(false);
				}
			}
		});
	}

	public void updateAgents() {
		GameController gmctrl = this.gmctrl;
		agentMenu.removeAll();
		if (gmctrl.getAgents() != null) {
			for (int i = 0; i < gmctrl.getAgents().size(); i++) {
				final int index = i;
				IAgent agent = gmctrl.getAgents().get(i);
				JCheckBoxMenuItem agentItem = new JCheckBoxMenuItem(agent.getAgentName());
				agentItem.setToolTipText(agent.getAgentDescription());
				agentItem.addActionListener(new ActionListener() {

					@Override
					public void actionPerformed(ActionEvent e) {
						gmctrl.selectAgent(index);
					}

				});
				agentMenu.add(agentItem);
			}
			agentMenu.addSeparator();
		}
		JCheckBoxMenuItem noAgent = new JCheckBoxMenuItem("不使用引擎");
		noAgent.setToolTipText("由您通过键盘控制贪吃蛇。");
		noAgent.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				gmctrl.selectAgent(-1);
			}

		});
		agentMenu.add(noAgent);
		this.gmctrl.selectAgent(this.gmctrl.getSelectedAgent() == null ? -1
				: this.gmctrl.getAgents().indexOf(this.gmctrl.getSelectedAgent()));
	}

	public void Show() {
		this.setVisible(true);
	}
}
